<template>
  <el-drawer v-model="drawerVisible" :destroy-on-close="true" size="450px" :title="`${drawerProps.title}系统配置`">
    <el-form
        ref="ruleFormRef"
        label-width="100px"
        label-suffix=" :"
        :rules="rules"
        :disabled="drawerProps.isView"
        :model="drawerProps.rowData"
        :hide-required-asterisk="drawerProps.isView"
    >
      <el-form-item label="类型" prop="type">
        <el-select v-model="drawerProps.rowData.type" placeholder="配置类型">
          <el-option v-for="item in drawerProps.configTypes" :key="item.type" :label="item.name" :value="item.type" />
        </el-select>
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="drawerProps.rowData.name" placeholder="配置名称" clearable />
      </el-form-item>
      <el-form-item label="编码" prop="code">
        <el-input v-model="drawerProps.rowData.code" placeholder="配置编码" clearable />
      </el-form-item>
      <el-form-item label="组件类型" prop="field_type">
        <el-select v-model="drawerProps.rowData.field_type" @change="handleValueTypeChange" placeholder="组件类型">
          <el-option v-for="item in drawerProps.fieldTypes" :key="item.type" :label="item.name" :value="item.type" />
        </el-select>
      </el-form-item>
      <el-form-item label="数据源" prop="data_source" v-if="drawerProps.rowData.field_type == 7">
        <el-select v-model="drawerProps.rowData.data_source" @change="handleDataSourceChange" placeholder="数据源" clearable>
          <el-option v-for="option in treeDataTypeEnum" :label="option.label" :value="option.value" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="showOptions" label="选项类型" prop="option_type">
        <el-select v-model="drawerProps.rowData.option_type" @change="handleOptionTypeChange" placeholder="选项类型" clearable>
          <el-option v-for="option in configValueOptionTypeEnum" :label="option.label" :value="option.value" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="showOptions" label="选项值" prop="option_value">
        <template v-if="drawerProps.rowData.option_type == 1">
          <el-select v-model="drawerProps.rowData.option_value" @change="handleDictChange" placeholder="选项值">
            <el-option v-for="option in drawerProps.dictList" :label="option.name" :value="option.id" />
          </el-select>
        </template>
        <template v-else>
          <el-input type="textarea" :rows="3" v-model="drawerProps.rowData.option_value" @change="handleOptionValueChange" placeholder="预设选项值JSON字符串" clearable />
        </template>
      </el-form-item>
      <el-form-item label="配置值" prop="value">
        <FormItem v-model="drawerProps.rowData" />
      </el-form-item>
      <el-form-item label="排序" prop="sort">
        <el-input-number v-model="drawerProps.rowData.sort" :min="0" placeholder="配置排序" style="width: 180px;" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="drawerProps.rowData.status">
          <el-radio :value="1">启用</el-radio>
          <el-radio :value="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="drawerVisible = false">取消</el-button>
      <el-button type="primary" v-show="!drawerProps.isView" @click="handleSubmit">确定</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from "vue";
import { ElMessage, FormInstance } from "element-plus";
import FormItem from '@/components/FormItem/index.vue';
import { configValueOptionTypeEnum, treeDataTypeEnum } from "@/config/enums/serviceDict.ts";
import {isArray, isNumeric, isString} from "@/helper/is.ts";
import {dictValueListApi} from "@/api/modules/dict.ts";
import {Recordable} from "@/interface/types.ts";

interface DrawerProps {
  title: string;
  isView: boolean;
  rowData?: any;
  configTypes: any[];
  fieldTypes: any[],
  dictList: any[];
  authTree: any[];
  deptTree: any[];
  cateTree: any[];
  dictValuesMap: Recordable;
  api?: (params: any) => Promise<any>;
  getTableList?: () => Promise<any>;
}

const rules = reactive<Recordable>({
  type: [{ required: true, message: "请选择配置类型" }],
  name: [{ required: true, message: "请输入配置名称" }],
  field_type: [{ required: true, message: "请选择字段类型" }],
  data_source: [],
  option_type: [],
  option_value: [],
  value: [{ required: true, message: "请输入配置值" }],
  status: [{ required: true, message: "请选择配置状态" }]
});

const dataSourceRules = [{ required: true, message: "请选择数据来源" }];
const optionTypeRules = [{ required: true, message: "请选择选项类型" }];
const optionValueRules = [{ required: true, message: "选项值不能为空" }];

// drawer框状态
const drawerVisible = ref(false);
const drawerProps = ref<DrawerProps>({
  isView: false,
  title: "",
  configTypes: [],
  fieldTypes: [],
  dictList: [],
  authTree: [],
  deptTree: [],
  cateTree: [],
  dictValuesMap: {},
});

const showOptions = computed(() => [3, 4, 5, 6].indexOf(drawerProps.value.rowData.field_type) > -1);

// 接收父组件传过来的参数
const acceptParams = (params: DrawerProps): void => {
  drawerProps.value = params;
  drawerVisible.value = true;
  drawerProps.value.dictValuesMap = {};
  handleValueTypeChange();
};

const handleValueTypeChange = () => {
  if (drawerProps.value.rowData.field_type == 2) {
    drawerProps.value.rowData.value = Number(drawerProps.value.rowData.value);
  } else if (drawerProps.value.rowData.field_type == 5) {
    drawerProps.value.rowData.value = drawerProps.value.rowData.value ? isArray(drawerProps.value.rowData.value) ? drawerProps.value.rowData.value : [drawerProps.value.rowData.value] : [];
  } else if (drawerProps.value.rowData.field_type == 7) {
    drawerProps.value.rowData.value = drawerProps.value.rowData.value ? drawerProps.value.rowData.value : '';
  } else {
    drawerProps.value.rowData.value += '';
  }
  if (showOptions.value) {
    rules.option_type.push(...optionTypeRules);
    rules.option_value.push(...optionValueRules);
    handleOptionTypeChange(drawerProps.value.rowData.option_type);
  } else if (drawerProps.value.rowData.field_type == 7) {
    rules.data_source.push(...dataSourceRules);
    handleDataSourceChange(drawerProps.value.rowData.data_source);
  } else {
    rules.option_type = [];
    rules.option_value = [];
    rules.data_source = [];
  }
}

const handleOptionTypeChange = (option_type: number) => {
  if (option_type == 1) {
    handleDictChange(drawerProps.value.rowData.option_value);
  } else if (option_type == 2) {
    handleOptionValueChange(drawerProps.value.rowData.option_value);
  }
}

const handleDictChange = async (option_value: number) => {
  if (!option_value) {
    return;
  }
  let data = drawerProps.value.dictValuesMap[option_value];
  if (!data) {
    const res = await dictValueListApi({dict_id: option_value});
    data = res.data as any[];
    drawerProps.value.dictValuesMap[option_value] = data;
  }
  assembleOptionValues(data);
}

const handleOptionValueChange = (option_value: string) => {
  if (!option_value) {
    return;
  }
  try {
    const jsonData = JSON.parse(option_value);
    assembleOptionValues(jsonData);
  } catch (err) {
    console.error("预设选项值JSON格式异常：", err);
  }
}

const assembleOptionValues = (data: any[]) => {
  drawerProps.value.rowData.options = [];
  data.map(item => {
    if (drawerProps.value.rowData.field_type == 3) {
      let flag = false;
      if (isNumeric(item.value)) {
        flag = Boolean(Number(item.value));
      } else if (isString(item.value)) {
        flag = item.value == 'true' ? true : item.value == 'false' ? false : Boolean(item.value);
      }
      if (flag) {
        drawerProps.value.rowData.active = item.value;
        drawerProps.value.rowData.active_text = item.name;
        drawerProps.value.rowData.active_icon = item.code;
      } else {
        drawerProps.value.rowData.inactive = item.value;
        drawerProps.value.rowData.inactive_text = item.name;
        drawerProps.value.rowData.inactive_icon = item.code;
      }
    } else {
      drawerProps.value.rowData.options.push({ name: item.name, value: item.value })
    }
  });
}

const handleDataSourceChange = (val: number) => {
  drawerProps.value.rowData.label = val == 1 ? "title" : "name";
  drawerProps.value.rowData.key = "id";
  drawerProps.value.rowData.treeData = val == 1 ? drawerProps.value.authTree : val == 2 ? drawerProps.value.deptTree : drawerProps.value.cateTree;
}

// 提交数据（新增/编辑）
const ruleFormRef = ref<FormInstance>();
const handleSubmit = () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      await drawerProps.value.api!(drawerProps.value.rowData);
      ElMessage.success({ message: `${drawerProps.value.title}配置成功！` });
      if (drawerProps.value.getTableList) {
        await drawerProps.value.getTableList();
      }
      drawerVisible.value = false;
    } catch (error) {
      console.log(error);
    }
  });
};

defineExpose({
  acceptParams
});
</script>
